
import java.security.*;
import java.util.*;
import javax.smartcardio.*;
import java.security.cert.CertificateException;


public class ObtenerDatos {

     public ObtenerDatos() throws Exception{

    }

     public String obtenerNombre(String PIN) throws Exception {
        String name = LeerDatos(PIN);
        return name;
    }

    private String LeerDatos(String PIN) throws Exception {


        String alias="";
        boolean found = false;
                
        Card c = ConexionTarjeta();
        if(c == null)
            throw new Exception("No se ha encontrado ninguna tarjeta");
       
        c.disconnect(true);

        try {
            
            String configName="";
            String osName = System.getProperty("os.name").toLowerCase();
                       
            if(osName.substring(0,7).compareTo("windows")==0)
                configName = "dnie_windows.cfg";
            else if(osName.substring(0,5).compareTo("linux")==0)
                    configName = "dnie_linux.cfg";
                else if(osName.substring(0,3).compareTo("mac")==0)
                        configName = "dnie_mac.cfg";

            Provider p = new sun.security.pkcs11.SunPKCS11(configName);
	    Security.addProvider(p);

            KeyStore keyStore = KeyStore.getInstance("PKCS11", p);
            char[] pin = PIN.toCharArray();

            keyStore.load(null, pin);
            

            Enumeration enumeration = keyStore.aliases();
            java.security.cert.Certificate certificado;

            do{
                alias = enumeration.nextElement().toString();
                if(alias.compareTo("CertAutenticacion")==0)
                    found=true;
                else
                    found=false;

            }while(enumeration.hasMoreElements() && found==false);

            if(found==true)
            {
                certificado = keyStore.getCertificate(alias);
                Key key = keyStore.getKey(alias, pin);

                if (key instanceof PrivateKey) {

                    boolean verSig;
                    byte[] data, realSig;

                    Signature sig = Signature.getInstance("SHA1withRSA");
                    sig.initSign((PrivateKey)key);
                    data = new String("Este texto sirbe para comprobar la firma del usuario del DNIe").getBytes();

                    sig.update(data);
                    realSig = sig.sign();

                    Signature sigver = Signature.getInstance("SHA1withRSA");
                    sigver.initVerify(certificado.getPublicKey());
                    sigver.update(data);

                    verSig = sigver.verify(realSig);
                    System.out.println("verSig: "+verSig);

                }
            }
            
        } catch (CertificateException e) {
	      System.err.println("Caught exception " + e.toString() + ". Compruebe que no ha introducido un pin.");

        } catch (Exception e) {
	      System.err.println("Caught exception " + e.toString());
        }

        return alias;
    }

    
    private Card ConexionTarjeta() throws Exception {
        
        Card card = null;
        TerminalFactory factory = TerminalFactory.getDefault();
        List<CardTerminal> terminals = factory.terminals().list();
        System.out.println("Terminals: " + terminals);

        for (int i = 0; i < terminals.size(); i++) {

            

            
            CardTerminal terminal = terminals.get(i);
            

            try {
                if(terminal.isCardPresent()) {
                    card = terminal.connect("*"); 

                }
		    } catch (Exception e) {

                System.out.println("Exception catched: " + e.getMessage());
                card = null;
		    }
        }
        return card;
    }

}

